﻿using MetroDataApi.Models;
using MetroDataQuery.Utility;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MetroDataApi.Controllers.DataQueryTable
{



    public class ChangeTableController : Controller
    {
        private JsonSerializerSettings jsonSerializerSettings = new JsonSerializerSettings()
        {
            ContractResolver = new CamelCasePropertyNamesContractResolver(),
            Converters = new List<JsonConverter> { new MyDateTimeConvertor() }
        };


        public ActionResult Index(int prjId, string names = "", string startTime = "",
               string endTime = "", string monitorType = "", string location = "", string json = "0")
        {
            if (json == "1")
            {
                return RedirectToAction("Get", new
                {
                    action = "Get",
                    prjId = prjId,
                    names = names,
                    startTime = startTime,
                    endTime = endTime,
                    monitorType = monitorType,
                    location = location
                });
            }
            else
            {
                List<string> nameList = names.Split(',').ToList();
                var items = new List<List<result>>();
                ViewBag.Items = items;
                return View();
            }
        }

        //json 实现
        public ContentResult Get(int prjId, string names = "", string startTime = "",
            string endTime = "", string monitorType = "", string location = "")
        {
            using (var db = new MetroDataDataContext())
            {
                //格式为3组,顺序是初始值,上次,本次
                var items = new List<List<result>> { new List<result>(), new List<result>(), new List<result>() };
                if (names != "")
                {
                    var nameList = names.Split(',').ToList();
                    var dictionList = PointsDictionaryQuery.GetDictPointByNameList(prjId, nameList);

                    foreach (var dict in dictionList)
                    {
                        var eachItems = this.Query(prjId, dict.MonitorType, dict.Location, startTime, endTime);
                        items[0].AddRange(eachItems[0]);
                        items[1].AddRange(eachItems[1]);
                        items[2].AddRange(eachItems[2]);
                    }
                    for (var i = 0; i < items.Count; i++)
                    {
                        items[i] = (from p in nameList
                                    join a in items[i]
                                        on p equals a.name
                                    select a).ToList();
                    }
                }
                else
                {
                    items = this.Query(prjId, monitorType, location, startTime, endTime);
                }
                return this.Content(JsonConvert.SerializeObject(items, Formatting.Indented, jsonSerializerSettings), "application/json");
            }
        }

        public ActionResult DataContent(int prjId, string fields = "date,number", string order = "asc", string split = ",", string json = "0")
        {
            //var datas = this.getMonitorPoints(prjId, type);
            if (json == "0")
            {
                var datas = this.getDataContentSummary(prjId, order);
                ViewBag.Datas = datas;
                ViewBag.Type = fields;
                ViewBag.Split = split.Length == 1 ? split : ",";
                ViewBag.Max = datas.Max(p => p.Count);
                return View();
            }
            else
            {
                return
                    RedirectToAction("DataContentJson", new { prjId = prjId, fields = fields, order = order, split = split });
            }

        }


        [HttpGet]
        public ContentResult DataContentJson(int prjId, string fields = "date,number", string order = "asc", string split = ",")
        {
            using (var db = new MetroDataDataContext())
            {
                var datas = this.getDataContentSummary(prjId, order);
                return this.Content(JsonConvert.SerializeObject(datas, Formatting.Indented, jsonSerializerSettings), "application/json");
            }
        }





        private List<List<result>> Query(int prjId, string monitorType, string location, string startTime = "", string endTime = "")
        {
            var items = new List<List<result>>();

            var times = Recent2Changes.get2Times(prjId, location, monitorType, startTime, endTime);

            //插入初始值时间
            times.Insert(0, QueryResults.GetOriginTime(prjId, monitorType, location));


            var originTime = times[0];
            var origins = QueryResults.GetOriginResults(prjId, monitorType, location);
            var last = QueryResults.GetResultsByDateTime(prjId, monitorType, location, times[1], false).ToList();
            var cur = QueryResults.GetResultsByDateTime(prjId, monitorType, location, times[2], false).ToList();

            last = (from o in origins
                    from p in last.Where(p => p.name == o.name).DefaultIfEmpty()
                    select p).ToList();

            cur = (from o in origins
                   from p in cur.Where(p => p.name == o.name).DefaultIfEmpty()
                   select p).ToList();

            items.Add(origins);
            items.Add(last);
            items.Add(cur);


            return items;
        }


        private List<DataContent> getDataContentSummary(int prjId, string order = "asc")
        {
            using (var db = new MetroDataDataContext())
            {
                var monitorLocationGroup = from p in db.MonitorPointsDictionary
                                           where p.PrjId == prjId
                                           group p by new { p.MonitorType, p.Location } into g
                                           select g;
                var aaa = new List<DataContent>();
                foreach (var g in monitorLocationGroup)
                {
                    var countList = MetroDataQuery.Utility.MonitorPointsQuery.GetPointsCountByTime(prjId,
                                    g.Key.MonitorType, g.Key.Location, order);

                    var item = new DataContent(g.Key.MonitorType, g.Key.Location)
                                {
                                    Items = countList.Select((p, index) => new DataContentItem()
                                    {
                                        Count = p.Count,
                                        Date = p.DateTime

                                    }).ToList()
                                };
                    aaa.Add(item);

                }
                return aaa;
            }
        }

    }

    public class DataContentItem
    {
        [Display(Name = "date")]
        public DateTime Date { get; set; }

        [Display(Name = "number")]
        public int Count { get; set; }

        public string Format(string paras, string split = ",")
        {
            var strs = paras.Split(',');
            var primaryPropList = this.GetType().GetProperties().
              Where(p => p.IsDefined(typeof(DisplayAttribute), false));
            var l = new List<string>();
            foreach (var s in strs)
            {
                var t = primaryPropList.SingleOrDefault(p => p.GetCustomAttributes(typeof(DisplayAttribute), true).
                               Cast<DisplayAttribute>().SingleOrDefault().Name == s);
                if (t == null) continue;
                if (t.PropertyType == typeof(DateTime))
                {
                    l.Add(Convert.ToDateTime(t.GetValue(this, null)).ToString("yyyy-MM-dd"));
                }
                else
                {
                    l.Add(t.GetValue(this, null).ToString());
                }
            }
            return string.Join(split, l.ToArray());
        }
    }

    public class DataContent
    {


        public string Title { get; set; }
        public List<DataContentItem> Items { get; set; }
        private int count = 0;
        public int Count
        {
            get { return this.Items.Count; }
            set
            {
                this.count = value;
            }
        }
        public string MonitorType { get; set; }
        public string Location { get; set; }


        public DataContent(string m = "", string l = "")
        {
            this.Count = 0;

            this.MonitorType = m;
            this.Location = l;
            this.Title = l + "-" + m;
        }
    }

    public class RecentTableChanges
    {
        public string lastTime { get; set; }
        public IEnumerable<result> lastValues { get; set; }

        public string curTime { get; set; }
        public IEnumerable<result> curValues { get; set; }


        public string originTime { get; set; }
        public IEnumerable<result> originValues { get; set; }


        public RecentTableChanges()
        {
            this.lastValues = new List<result>();
            this.curValues = new List<result>();
            this.originValues = new List<result>();
        }
    }
}
